﻿//本文件由贺镇涛(2021300004071) 高肇鸿(学号) 共同负责
// 定义矩阵和行列式运算-------------------- 

#include"Matanddet.h"
using namespace std;
#include<iostream>
#include<cmath>

//贺：
double Mat::order_judge(double matrix[26][26], int order)//判断阶数
{
	if (order == 1)return matrix[1][1];
	else if (order == 2)return (matrix[1][1] * matrix[2][2] - matrix[1][2] * matrix[2][1]);
	else
	{
		double result = 0, cof;
		for (int j = 1; j <= order; j++)
		{
			cof = laplace_expansion(matrix, 1, j, order);//得到a[i][j]的余子式Acof_{i,j}
			result += pow(-1, 1 + j) * matrix[1][j] * cof;
		}
		return result;
	}
}

double Mat::laplace_expansion(double matrix[26][26], int i0, int j0, int order)//利用拉普拉斯展开求矩阵的行列式//矩阵，项的下标，矩阵的阶
{
	double result = 0, cof[26][26];
	int original_i, original_j;
	for (int i = 1; i <= order; i++)//获得余子式
	{
		for (int j = 1; j <= order; j++)
		{
			original_i = i;
			original_j = j;
			if (i == i0 || j == j0);
			else
			{
				if (i > i0)
					i--;
				if (j > j0)
					j--;
				cof[i][j] = matrix[original_i][original_j];
				i = original_i;
				j = original_j;
			}
		}
	}
	result = order_judge(cof, order - 1);
	return result;
}

void Mat::transpo()
{
	double b[26][26] = {};
	for (int i = 1; i <= m; i++)
	{
		for (int j = 1; j <= n; j++)
		{
			b[j][i] = a[i][j];
		}
	}
	int temp;
	temp = m;
	m = n;
	n = temp;
	for (int i = 1; i <= m; i++)
	{
		for (int j = 1; j <= n; j++)
		{
			a[i][j] = b[i][j];
		}
	}
}

double Mat::det_cal()
{
	if (m != n) { cout << "矩阵不合法：不为方阵"; return -1; }
	else return order_judge(a, m);
}

//高：
//矩阵加法
void Mat_cal::add(double adda[26][26], double addb[26][26], int ma, int mb, int na, int nb)
{
	if (ma != mb || na != nb) {
		cout << "数学错误，矩阵行列不同" << endl;
	}
	else {
		for (int i = 1; i <= ma; i++)
		{
			for (int j = 1; j <= na; j++)
			{
				cout << adda[i][j] + addb[i][j] << " ";
			}
			cout << endl;
		}
	}
}

//矩阵减法
void Mat_cal::subtract(double suba[26][26], double subb[26][26], int ma, int mb, int na, int nb)
{
	if (ma != mb || na != nb) {
		cout << "数学错误，矩阵行列不同" << endl;
	}
	else {
		for (int i = 1; i <= ma; i++)
		{
			for (int j = 1; j <= na; j++)
			{
				cout << suba[i][j] - subb[i][j] << " ";
			}
			cout << endl;
		}
	}
}

//矩阵乘法
void Mat_cal::multiply(double mula[26][26], double mulb[26][26], int ma, int na, int mb, int nb)
{
	if (na != mb) {
		cout << "数学错误，矩阵a列数与矩阵b行数不同" << endl;
	}
	else {
		double temp = 0;
		for (int i = 1; i <= ma; i++)
		{
			for (int j = 1; j <= nb; j++)
			{
				temp = 0;
				for (int k = 1; k <= na; k++)
				{
					temp += mula[i][k] * mulb[k][j];
				}
				cout << temp << " ";
			}
			cout << endl;
		}
	}
}

int matanddet(string s)//单独编写使用main()//需要第一行按下空格
{
	int m, n, choice, ma, mb, na, nb;	//m,n,ma,mb,na,nb为行数、列数
	/*cutter(s);
	m = atoi(str_cut[0].c_str());
	n = atoi(str_cut[1].c_str());
	cout << m <<" " << n;*/
	cout << "请选择功能:" << endl;
	cout << "0-求矩阵行列式及其转置矩阵" << endl;
	cout << "1-矩阵间的加法" << endl;
	cout << "2-矩阵间的减法" << endl;
	cout << "3-矩阵间的乘法" << endl;
	cout << "4-求矩阵的逆矩阵" << endl;
	cin >> choice;
	switch (choice)
	{
	case 0:
	{
		cout << "0-求行列式及转置矩阵" << endl;
		cout << "请输入您定义的矩阵的行数和列数，让后回车输入矩阵:" << endl;
		cin >> m >> n;
		Mat new_mat(m, n);
		cout << "您输入的矩阵是：" << endl;
		new_mat.print();
		cout << "转置之后是:" << endl;
		new_mat.transpo();
		new_mat.print();
		cout << "其行列式为:" << endl;
		double result = new_mat.det_cal();
		cout << result;
		break;
	}
	case 1:
	{
		cout << "1-矩阵间的加法" << endl;
		cout << "A+B=C" << endl;
		cout << "请输入矩阵A的行数和列数，然后回车输入矩阵:" << endl;
		cin >> ma >> na;
		Mat add_a(ma, na);
		cout << "请输入矩阵B的行数和列数，然后回车输入矩阵:" << endl;
		cin >> mb >> nb;
		Mat add_b(mb, nb);
		cout << "求和结果为:" << endl;
		Mat_cal::add(add_a.a, add_b.a, ma, mb, na, nb);
		break;
	}
	case 2:
	{
		cout << "2-矩阵间的减法" << endl;
		cout << "A-B=C" << endl;
		cout << "请输入矩阵A的行数和列数，然后回车输入矩阵:" << endl;
		cin >> ma >> na;
		Mat sub_a(ma, na);
		cout << "请输入矩阵B的行数和列数，然后回车输入矩阵:" << endl;
		cin >> mb >> nb;
		Mat sub_b(mb, nb);
		cout << "求差结果为:" << endl;
		Mat_cal::subtract(sub_a.a, sub_b.a, ma, mb, na, nb);
		break;
	}
	case 3:
	{
		cout << "3-矩阵间的乘法" << endl;
		cout << "A*B=C" << endl;
		cout << "请输入矩阵A的行数和列数，然后回车输入矩阵:" << endl;
		cin >> ma >> na;
		Mat mul_a(ma, na);
		cout << "请输入矩阵B的行数和列数，然后回车输入矩阵:" << endl;
		cin >> mb >> nb;
		Mat mul_b(mb, nb);
		cout << "求积结果为:" << endl;
		Mat_cal::multiply(mul_a.a, mul_b.a, ma, mb, na, nb);
		break;
	}
	case 4:
	{
		cout << "4-求矩阵的逆矩阵" << endl;
		cout << "B=A^(-1)" << endl;
		cout << "请输入矩阵A的行数与列数，然后回车输入矩阵:" << endl;
		cin >> ma >> na;
		Matfix inv_b(ma, na);
		Mat inv_a(ma, na);

		double result = inv_a.det_cal();
		if (result == 0)
		{
			cout << "行列式为零，不存在逆矩阵" << endl;
		}
		else
		{
			Mat_cal::inverse(&inv_a, &inv_b);
			cout << "A的逆矩阵为:" << endl;
			for (int i = 1; i <= ma; i++)
			{
				for (int j = 1; j <= na; j++)
				{
					cout << inv_b.read_mat(i, j) << " ";
				}
				cout << endl;
			}
		}
		break;
	}
	}
	return 0;
}